package cn.llin.web.controller.system;

import cn.llin.common.core.controller.BaseController;
import cn.llin.common.core.domain.AjaxResult;
import cn.llin.common.core.text.Convert;
import cn.llin.common.utils.QrCodeUtils;
import cn.llin.common.utils.ServletUtils;
import cn.llin.common.utils.StringUtils;
import cn.llin.framework.web.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * 登录验证
 *
 * @author sys-manage
 */
@Slf4j
@Controller
public class SysLoginController extends BaseController {
    /**
     * 是否开启记住我功能
     */
    @Value("${shiro.rememberMe.enabled: false}" )
    private boolean rememberMe;

    @Autowired
    private ConfigService configService;

    @GetMapping("/login" )
    public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap) {
        // 如果是Ajax请求，返回Json字符串。
        if (ServletUtils.isAjaxRequest(request)) {
            return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}" );
        }
        // 是否开启记住我
        mmap.put("isRemembered" , rememberMe);
        // 是否开启用户注册
        mmap.put("isAllowRegister" , Convert.toBool(configService.getKey("sys.account.registerUser" ), false));
        return "login" ;
    }

    @PostMapping("/login" )
    @ResponseBody
    public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe) {
        UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            return success();
        } catch (AuthenticationException e) {
            log.error("用户或密码错误" , e);
            String msg = "用户或密码错误" ;
            if (StringUtils.isNotEmpty(e.getMessage())) {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }

    @GetMapping("/unauth" )
    public String unauth() {
        return "error/unauth" ;
    }


    /** ============= 以下开始为微信扫码登录功能  ============= */

    /**
     * 获取微信登录二维码
     *
     * @param request
     * @param response
     * @return
     */
    @GetMapping(value = "/getWeixinLoginImage" )
    public ModelAndView getWeixinLoginImage(HttpServletRequest request, HttpServletResponse response) {
        String loginImageId = request.getParameter("loginImageId" );
        ServletOutputStream out = null;
        try {
            HttpSession session = request.getSession();
            response.setDateHeader("Expires" , 0);
            response.setHeader("Cache-Control" , "no-store, no-cache, must-revalidate" );
            response.addHeader("Cache-Control" , "post-check=0, pre-check=0" );
            response.setHeader("Pragma" , "no-cache" );
            response.setContentType("image/jpeg" );

            // 生成二维码图片到本地
            String url = "";
            if (StringUtils.isEmpty(url)) {
                url = "获取登录二维码异常，请（点击）刷新登录二维码！" ;// 这里可以放获取失败的页面
            }
            BufferedImage bi = QrCodeUtils.encodePRToBufferedImage(url, 180, 180);

//            response.setHeader("LoginImage", url);
            out = response.getOutputStream();
            ImageIO.write(bi, "png" , out);
            out.flush();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
            }
        }
        return null;
    }

    /**
     * 查询登录二维码状态
     *
     * @param loginImageId
     * @return
     */
    @PostMapping(value = "/getWeixinLoginImageState" )
    @ResponseBody
    public AjaxResult getWeixinLoginImageState(@NotNull @Valid String loginImageId) {
        logger.info("查询登录二维码状态：" + loginImageId);
        try {
//            WeixinLoginImageStateEnum state = weixinLoginService.selectLoginImageUrlState(loginImageId);
//
//            if (state == null)
//                return error("登录二维码已失效" );
//
//            // 登录
//            if ((WeixinLoginImageStateEnum.LOGIN_SUCCEEDED.name()).equals(state.name())) {
//                SysUser sysUser = weixinLoginService.getRedis(loginImageId);
//                ajaxLogin(sysUser.getLoginName(), sysUser.getPassword(), false);
//            }
//            return success(state.name());

            return success();

        } catch (Exception e) {
            String msg = "查询登录二维码状态异常" ;
            logger.error(msg, e);
            if (StringUtils.isNotEmpty(e.getMessage())) {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }

    /**
     * 错误时就到新浪[坏笑]
     */
    public static final String ERROR_REDIRECT_URL = "https://www.sina.com.cn/" ;


    /**
     * 微信获取openid需要的重定向回调地址
     *
     * @param request
     * @param response
     */
    @GetMapping(value = "/weixinRedirect" )
    public void weixinRedirect(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 获取二维码ID、获取用户code
        String code = request.getParameter("code" );
        String loginImageId = request.getParameter("loginImageId" );

        if (StringUtils.isBlank(code) || StringUtils.isBlank(loginImageId)) {
            response.sendRedirect(ERROR_REDIRECT_URL + System.currentTimeMillis());
            return;
        }

        String respHtmlStr = getRespHtmlStr("登录失败" , "登录失败，请（点击）刷新登录二维码！" );

        // 拦截非微信浏览器
        String userAgent = request.getHeader("user-agent" );
        String wx_browser = "MicroMessenger" ;// 微信浏览器标识
        if (StringUtils.isBlank(code) || userAgent.indexOf(wx_browser) == -1) {// 不存在包含关系，返回的值等于-1
            getRespHtmlStr("登录失败" , "登录失败，请使用手机微信扫一扫！" );
        }

        /*SysUser sysUser = weixinLoginService.getSysUserBycode(code, loginImageId);
        if (sysUser != null) {
            weixinLoginService.setRedis(loginImageId, sysUser);
            // 展示登录成功的页面
//            TimeUnit.SECONDS.sleep(2);
            respHtmlStr = getRespHtmlStr("登录成功" , "Login Succeeded, Welcome!" );
        }*/
        response.setContentType("text/html;charset=utf-8" );
        response.getWriter().write(respHtmlStr);

    }

    private static String getRespHtmlStr(String title, String content) {
        StringBuffer sf = new StringBuffer();

        sf.append("<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><title>" + title + "</title></head><body><div style=\"font-size: 200%\">" );
        sf.append("<h3>" + content + "</h3><hr>" );

        return sf.toString().replace("null" , "" );
    }

}
